use super::*;
pub trait Win: Sized + 'static {
	type Error: std::error::Error;
	type WinRaw;
	type Attr: WinAttr;
	type WinHandle: WinHandle<Self>;
	type WinRef<'a>: WinRef<Self::WinRaw> + Copy;
	//
	type Mouse<'a>: IntoEvt<Self, Mouse>;
	type Wheel<'a>: IntoEvt<Self, Wheel>;
	type Keyboard<'a>: IntoEvt<Self, Keyboard>;
	type Touch<'a>: IntoEvt<Self, Touch>;
	type Ime<'a>: IntoEvt<Self, Ime>;
	//
	fn win(key: impl AsRef<str>, attr: Self::Attr, rep: impl WinRep<Self>) -> Result<Self::WinHandle, Self::Error>;
}
pub trait WinRep<P: Win>: 'static {
	fn on_create(&self, win: P::WinRef<'_>) {
		win.show();
	}
	fn on_start(&self, _: P::WinRef<'_>) {} // visible
	fn on_resume(&self, _: P::WinRef<'_>) {} // gain focus

	fn on_pause(&self, _: P::WinRef<'_>) {} // covered by another lost focus
	fn on_stop(&self, _: P::WinRef<'_>) {} // no longer visible
	fn on_destroy(&self, _: P::WinRef<'_>) {}

	fn on_proxy(&self, _: P::WinRef<'_>, _: i64) {}

	fn on_resize(&self, _: P::WinRef<'_>, _size: (u32, u32)) {}

	fn on_mouse(&self, _: P::WinRef<'_>, _evt: P::Mouse<'_>) -> bool {
		false
	}
	fn on_touch(&self, _: P::WinRef<'_>, _evt: P::Touch<'_>) -> bool {
		false
	}
	fn on_wheel(&self, _: P::WinRef<'_>, _evt: P::Wheel<'_>) -> bool {
		false
	}
	fn on_keyboard(&self, _: P::WinRef<'_>, _evt: P::Keyboard<'_>) -> bool {
		false
	}
	fn on_ime(&self, _: P::WinRef<'_>, _evt: P::Ime<'_>) -> bool {
		false
	}

	fn on_req_close(&self, _: P::WinRef<'_>) -> bool {
		true
	}
	fn on_req_draw(&self, _: P::WinRef<'_>, _nanos: i64) {}
}
pub trait WinRef<WinRaw> {
	fn raw(&self) -> Option<WinRaw>;
	fn size(&self) -> (u32, u32);
	fn density(&self) -> f32;
	//
	fn fresh(&self, _: &str);
	fn close(&self);
	fn show(&self);
}
pub trait WinHandle<P: Win>: Sized {
	fn with(&self, _: impl FnOnce(P::WinRef<'_>));
}
pub trait WinAttr: Sized + Default {
	fn size(&mut self, _: (u32, u32));
	fn pos(&mut self, _: (i32, i32));
	fn title(&mut self, _: String);
	fn resizable(&mut self, _: bool);
	fn minimizable(&mut self, _: bool);
	fn maximizable(&mut self, _: bool);
	fn closable(&mut self, _: bool);
}

pub struct XwinAttr {
	pub size: Option<(u32, u32)>,
	pub pos: Option<(i32, i32)>,
	pub title: String,
	pub resizable: bool,
	pub minimizable: bool,
	pub maximizable: bool,
	pub closable: bool,
}
impl Default for XwinAttr {
	fn default() -> Self {
		Self {
			size: None,
			pos: None,
			title: String::new(),
			resizable: true,
			minimizable: true,
			maximizable: true,
			closable: true,
		}
	}
}
impl WinAttr for XwinAttr {
	fn size(&mut self, v: (u32, u32)) {
		self.size = Some(v)
	}
	fn pos(&mut self, v: (i32, i32)) {
		self.pos = Some(v)
	}
	fn title(&mut self, v: String) {
		self.title = v;
	}
	fn resizable(&mut self, v: bool) {
		self.resizable = v;
	}
	fn minimizable(&mut self, v: bool) {
		self.minimizable = v;
	}
	fn maximizable(&mut self, v: bool) {
		self.maximizable = v;
	}
	fn closable(&mut self, v: bool) {
		self.closable = v;
	}
}
